package tenumn.energytech.registrys.machine;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.EnergyStorage;
import net.minecraftforge.fluids.capability.IFluidHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tenumn.energytech.registrys.CapabilitiesRegistry;
import tenumn.energytech.registrys.FluidRegistry;
import tenumn.energytech.registrys.capability.GasTank;

import javax.annotation.ParametersAreNonnullByDefault;

@ParametersAreNonnullByDefault
public class SteamEngineBlockEntity extends MachineBlockEntity {
    GasTank gasTank = new GasTank(500000, fluidStack -> fluidStack.getFluid().isSame(FluidRegistry.steam.get()));
    EnergyStorage energyStorage = new EnergyStorage(Integer.MAX_VALUE);

    public SteamEngineBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
        super(pType, pWorldPosition, pBlockState);
    }

    @NotNull
    @Override
    public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        if (cap == CapabilitiesRegistry.GAS_CAPABILITY)
            return LazyOptional.of(() -> gasTank).cast();
        if (cap == CapabilityEnergy.ENERGY)
            return LazyOptional.of(() -> energyStorage).cast();
        return super.getCapability(cap, side);
    }

    @Override
    protected void saveAdditional(CompoundTag pTag) {
        super.saveAdditional(pTag);
        pTag.put("Gas", gasTank.writeToNBT(new CompoundTag()));
        pTag.put("FE", energyStorage.serializeNBT());
    }

    @Override
    public void load(CompoundTag pTag) {
        super.load(pTag);
        gasTank.readFromNBT(pTag.getCompound("Gas"));
        energyStorage.deserializeNBT(pTag.get("FE"));
    }

    @Override
    public void tick() {
        if (level instanceof ServerLevel) {
            energyStorage.receiveEnergy(gasTank.drain(1, IFluidHandler.FluidAction.EXECUTE).getAmount() * 8, false);
            for (Direction direction : Direction.values()) {
                var be = level.getBlockEntity(getBlockPos().relative(direction));
                if (be != null) be.getCapability(CapabilityEnergy.ENERGY).ifPresent(e -> {
                    int amount = e.receiveEnergy(energyStorage.extractEnergy(10, true), true);
                    e.receiveEnergy(energyStorage.extractEnergy(amount, false), false);
                });
            }
            level.blockEntityChanged(getBlockPos());
        }
    }
}
